gdkasync.c \
gdkasync.h \
gdkcursor-x11.c \
- gdkdevice-core.h \
- gdkdevice-core.c \
- gdkdevicemanager-core.h \
- gdkdevicemanager-core.c \
+ gdkdevice-core-x11.c \
+ gdkdevicemanager-core-x11.c \
gdkdevicemanager-x11.c \
gdkdisplaymanager-x11.c \
gdkdisplay-x11.c \
libgdkx11include_HEADERS = \
gdkx11cursor.h \
+ gdkx11device-core.h \
+ gdkx11devicemanager-core.h \
gdkx11display.h \
gdkx11displaymanager.h \
gdkx11keys.h \
--- /dev/null
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkx11device-core.h"
+
+#include "gdkinternals.h"
+#include "gdkwindow.h"
+#include "gdkprivate-x11.h"
+#include "gdkasync.h"
+
+static gboolean gdk_x11_device_core_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ gint *n_events);
+static void gdk_x11_device_core_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask);
+static void gdk_x11_device_core_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor);
+static void gdk_x11_device_core_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y);
+static gboolean gdk_x11_device_core_query_state (GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow **root_window,
+ GdkWindow **child_window,
+ gint *root_x,
+ gint *root_y,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask);
+static GdkGrabStatus gdk_x11_device_core_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_);
+static void gdk_x11_device_core_ungrab (GdkDevice *device,
+ guint32 time_);
+static GdkWindow * gdk_x11_device_core_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel);
+static void gdk_x11_device_core_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask);
+
+G_DEFINE_TYPE (GdkX11DeviceCore, gdk_x11_device_core, GDK_TYPE_DEVICE)
+
+static void
+gdk_x11_device_core_class_init (GdkX11DeviceCoreClass *klass)
+{
+ GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
+
+ device_class->get_history = gdk_x11_device_core_get_history;
+ device_class->get_state = gdk_x11_device_core_get_state;
+ device_class->set_window_cursor = gdk_x11_device_core_set_window_cursor;
+ device_class->warp = gdk_x11_device_core_warp;
+ device_class->query_state = gdk_x11_device_core_query_state;
+ device_class->grab = gdk_x11_device_core_grab;
+ device_class->ungrab = gdk_x11_device_core_ungrab;
+ device_class->window_at_position = gdk_x11_device_core_window_at_position;
+ device_class->select_window_events = gdk_x11_device_core_select_window_events;
+}
+
+static void
+gdk_x11_device_core_init (GdkX11DeviceCore *device_core)
+{
+ GdkDevice *device;
+
+ device = GDK_DEVICE (device_core);
+
+ _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
+ _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
+}
+
+static gboolean
+impl_coord_in_window (GdkWindow *window,
+ int impl_x,
+ int impl_y)
+{
+ if (impl_x < window->abs_x ||
+ impl_x >= window->abs_x + window->width)
+ return FALSE;
+
+ if (impl_y < window->abs_y ||
+ impl_y >= window->abs_y + window->height)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+gdk_x11_device_core_get_history (GdkDevice *device,
+ GdkWindow *window,
+ guint32 start,
+ guint32 stop,
+ GdkTimeCoord ***events,
+ gint *n_events)
+{
+ XTimeCoord *xcoords;
+ GdkTimeCoord **coords;
+ GdkWindow *impl_window;
+ int tmp_n_events;
+ int i, j;
+
+ impl_window = _gdk_window_get_impl_window (window);
+ xcoords = XGetMotionEvents (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (impl_window),
+ start, stop, &tmp_n_events);
+ if (!xcoords)
+ return FALSE;
+
+ coords = _gdk_device_allocate_history (device, tmp_n_events);
+
+ for (i = 0, j = 0; i < tmp_n_events; i++)
+ {
+ if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
+ {
+ coords[j]->time = xcoords[i].time;
+ coords[j]->axes[0] = xcoords[i].x - window->abs_x;
+ coords[j]->axes[1] = xcoords[i].y - window->abs_y;
+ j++;
+ }
+ }
+
+ XFree (xcoords);
+
+ /* free the events we allocated too much */
+ for (i = j; i < tmp_n_events; i++)
+ {
+ g_free (coords[i]);
+ coords[i] = NULL;
+ }
+
+ tmp_n_events = j;
+
+ if (tmp_n_events == 0)
+ {
+ gdk_device_free_history (coords, tmp_n_events);
+ return FALSE;
+ }
+
+ if (n_events)
+ *n_events = tmp_n_events;
+
+ if (events)
+ *events = coords;
+ else if (coords)
+ gdk_device_free_history (coords, tmp_n_events);
+
+ return TRUE;
+}
+
+static void
+gdk_x11_device_core_get_state (GdkDevice *device,
+ GdkWindow *window,
+ gdouble *axes,
+ GdkModifierType *mask)
+{
+ gint x_int, y_int;
+
+ gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+ if (axes)
+ {
+ axes[0] = x_int;
+ axes[1] = y_int;
+ }
+}
+
+static void
+gdk_x11_device_core_set_window_cursor (GdkDevice *device,
+ GdkWindow *window,
+ GdkCursor *cursor)
+{
+ Cursor xcursor;
+
+ if (!cursor)
+ xcursor = None;
+ else
+ xcursor = gdk_x11_cursor_get_xcursor (cursor);
+
+ XDefineCursor (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ xcursor);
+}
+
+static void
+gdk_x11_device_core_warp (GdkDevice *device,
+ GdkScreen *screen,
+ gint x,
+ gint y)
+{
+ Display *xdisplay;
+ Window dest;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
+ dest = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
+
+ XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
+}
+
+static gboolean
+gdk_x11_device_core_query_state (GdkDevice *device,
+ GdkWindow *window,
+ GdkWindow **root_window,
+ GdkWindow **child_window,
+ gint *root_x,
+ gint *root_y,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask)
+{
+ GdkDisplay *display;
+ GdkScreen *default_screen;
+ Window xroot_window, xchild_window;
+ int xroot_x, xroot_y, xwin_x, xwin_y;
+ unsigned int xmask;
+
+ display = gdk_window_get_display (window);
+ default_screen = gdk_display_get_default_screen (display);
+
+ if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
+ {
+ if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &xroot_window,
+ &xchild_window,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &xmask))
+ return FALSE;
+ }
+ else
+ {
+ XSetWindowAttributes attributes;
+ Display *xdisplay;
+ Window xwindow, w;
+
+ /* FIXME: untrusted clients not multidevice-safe */
+ xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
+ xwindow = GDK_SCREEN_XROOTWIN (default_screen);
+
+ w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
+ CopyFromParent, InputOnly, CopyFromParent,
+ 0, &attributes);
+ XQueryPointer (xdisplay, w,
+ &xroot_window,
+ &xchild_window,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &xmask);
+ XDestroyWindow (xdisplay, w);
+ }
+
+ if (root_window)
+ *root_window = gdk_x11_window_lookup_for_display (display, xroot_window);
+
+ if (child_window)
+ *child_window = gdk_x11_window_lookup_for_display (display, xchild_window);
+
+ if (root_x)
+ *root_x = xroot_x;
+
+ if (root_y)
+ *root_y = xroot_y;
+
+ if (win_x)
+ *win_x = xwin_x;
+
+ if (win_y)
+ *win_y = xwin_y;
+
+ if (mask)
+ *mask = xmask;
+
+ return TRUE;
+}
+
+static GdkGrabStatus
+gdk_x11_device_core_grab (GdkDevice *device,
+ GdkWindow *window,
+ gboolean owner_events,
+ GdkEventMask event_mask,
+ GdkWindow *confine_to,
+ GdkCursor *cursor,
+ guint32 time_)
+{
+ GdkDisplay *display;
+ Window xwindow, xconfine_to;
+ gint status;
+
+ display = gdk_device_get_display (device);
+
+ xwindow = GDK_WINDOW_XID (window);
+
+ if (confine_to)
+ confine_to = _gdk_window_get_impl_window (confine_to);
+
+ if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
+ xconfine_to = None;
+ else
+ xconfine_to = GDK_WINDOW_XID (confine_to);
+
+#ifdef G_ENABLE_DEBUG
+ if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
+ status = GrabSuccess;
+ else
+#endif
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ {
+ /* Device is a keyboard */
+ status = XGrabKeyboard (GDK_DISPLAY_XDISPLAY (display),
+ xwindow,
+ owner_events,
+ GrabModeAsync, GrabModeAsync,
+ time_);
+ }
+ else
+ {
+ Cursor xcursor;
+ guint xevent_mask;
+ gint i;
+
+ /* Device is a pointer */
+ if (!cursor)
+ xcursor = None;
+ else
+ {
+ _gdk_x11_cursor_update_theme (cursor);
+ xcursor = gdk_x11_cursor_get_xcursor (cursor);
+ }
+
+ xevent_mask = 0;
+
+ for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
+ {
+ if (event_mask & (1 << (i + 1)))
+ xevent_mask |= _gdk_x11_event_mask_table[i];
+ }
+
+ /* We don't want to set a native motion hint mask, as we're emulating motion
+ * hints. If we set a native one we just wouldn't get any events.
+ */
+ xevent_mask &= ~PointerMotionHintMask;
+
+ status = XGrabPointer (GDK_DISPLAY_XDISPLAY (display),
+ xwindow,
+ owner_events,
+ xevent_mask,
+ GrabModeAsync, GrabModeAsync,
+ xconfine_to,
+ xcursor,
+ time_);
+ }
+
+ _gdk_x11_display_update_grab_info (display, device, status);
+
+ return _gdk_x11_convert_grab_status (status);
+}
+
+static void
+gdk_x11_device_core_ungrab (GdkDevice *device,
+ guint32 time_)
+{
+ GdkDisplay *display;
+ gulong serial;
+
+ display = gdk_device_get_display (device);
+ serial = NextRequest (GDK_DISPLAY_XDISPLAY (display));
+
+ if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
+ XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_);
+ else
+ XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_);
+
+ _gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial);
+}
+
+static GdkWindow *
+gdk_x11_device_core_window_at_position (GdkDevice *device,
+ gint *win_x,
+ gint *win_y,
+ GdkModifierType *mask,
+ gboolean get_toplevel)
+{
+ GdkDisplay *display;
+ GdkScreen *screen;
+ Display *xdisplay;
+ GdkWindow *window;
+ Window xwindow, root, child, last;
+ int xroot_x, xroot_y, xwin_x, xwin_y;
+ unsigned int xmask;
+
+ last = None;
+ display = gdk_device_get_display (device);
+ screen = gdk_display_get_default_screen (display);
+
+ /* This function really only works if the mouse pointer is held still
+ * during its operation. If it moves from one leaf window to another
+ * than we'll end up with inaccurate values for win_x, win_y
+ * and the result.
+ */
+ gdk_x11_display_grab (display);
+
+ xdisplay = GDK_SCREEN_XDISPLAY (screen);
+ xwindow = GDK_SCREEN_XROOTWIN (screen);
+
+ if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
+ {
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &xmask);
+
+ if (root == xwindow)
+ xwindow = child;
+ else
+ xwindow = root;
+ }
+ else
+ {
+ gint i, screens, width, height;
+ GList *toplevels, *list;
+ Window pointer_window, root, child;
+ int rootx = -1, rooty = -1;
+ int winx, winy;
+ unsigned int xmask;
+
+ /* FIXME: untrusted clients case not multidevice-safe */
+ pointer_window = None;
+ screens = gdk_display_get_n_screens (display);
+
+ for (i = 0; i < screens; ++i)
+ {
+ screen = gdk_display_get_screen (display, i);
+ toplevels = gdk_screen_get_toplevel_windows (screen);
+ for (list = toplevels; list != NULL; list = g_list_next (list))
+ {
+ window = GDK_WINDOW (list->data);
+ xwindow = GDK_WINDOW_XID (window);
+ gdk_x11_display_error_trap_push (display);
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child,
+ &rootx, &rooty,
+ &winx, &winy,
+ &xmask);
+ if (gdk_x11_display_error_trap_pop (display))
+ continue;
+ if (child != None)
+ {
+ pointer_window = child;
+ break;
+ }
+ gdk_window_get_geometry (window, NULL, NULL, &width, &height);
+ if (winx >= 0 && winy >= 0 && winx < width && winy < height)
+ {
+ /* A childless toplevel, or below another window? */
+ XSetWindowAttributes attributes;
+ Window w;
+
+ w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
+ CopyFromParent, InputOnly, CopyFromParent,
+ 0, &attributes);
+ XMapWindow (xdisplay, w);
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child,
+ &rootx, &rooty,
+ &winx, &winy,
+ &xmask);
+ XDestroyWindow (xdisplay, w);
+ if (child == w)
+ {
+ pointer_window = xwindow;
+ break;
+ }
+ }
+ }
+
+ g_list_free (toplevels);
+ if (pointer_window != None)
+ break;
+ }
+
+ xwindow = pointer_window;
+ }
+
+ while (xwindow)
+ {
+ last = xwindow;
+ gdk_x11_display_error_trap_push (display);
+ XQueryPointer (xdisplay, xwindow,
+ &root, &xwindow,
+ &xroot_x, &xroot_y,
+ &xwin_x, &xwin_y,
+ &xmask);
+ if (gdk_x11_display_error_trap_pop (display))
+ break;
+
+ if (get_toplevel && last != root &&
+ (window = gdk_x11_window_lookup_for_display (display, last)) != NULL &&
+ window->window_type != GDK_WINDOW_FOREIGN)
+ {
+ xwindow = last;
+ break;
+ }
+ }
+
+ gdk_x11_display_ungrab (display);
+
+ window = gdk_x11_window_lookup_for_display (display, last);
+
+ if (win_x)
+ *win_x = (window) ? xwin_x : -1;
+
+ if (win_y)
+ *win_y = (window) ? xwin_y : -1;
+
+ if (mask)
+ *mask = xmask;
+
+ return window;
+}
+
+static void
+gdk_x11_device_core_select_window_events (GdkDevice *device,
+ GdkWindow *window,
+ GdkEventMask event_mask)
+{
+ GdkEventMask filter_mask, window_mask;
+ guint xmask = 0;
+ gint i;
+
+ window_mask = gdk_window_get_events (window);
+ filter_mask = (GDK_POINTER_MOTION_MASK &
+ GDK_POINTER_MOTION_HINT_MASK &
+ GDK_BUTTON_MOTION_MASK &
+ GDK_BUTTON1_MOTION_MASK &
+ GDK_BUTTON2_MOTION_MASK &
+ GDK_BUTTON3_MOTION_MASK &
+ GDK_BUTTON_PRESS_MASK &
+ GDK_BUTTON_RELEASE_MASK &
+ GDK_KEY_PRESS_MASK &
+ GDK_KEY_RELEASE_MASK &
+ GDK_ENTER_NOTIFY_MASK &
+ GDK_LEAVE_NOTIFY_MASK &
+ GDK_FOCUS_CHANGE_MASK &
+ GDK_PROXIMITY_IN_MASK &
+ GDK_PROXIMITY_OUT_MASK &
+ GDK_SCROLL_MASK);
+
+ /* Filter out non-device events */
+ event_mask &= filter_mask;
+
+ /* Unset device events on window mask */
+ window_mask &= ~(filter_mask);
+
+ /* Combine masks */
+ event_mask |= window_mask;
+
+ for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
+ {
+ if (event_mask & (1 << (i + 1)))
+ xmask |= _gdk_x11_event_mask_table[i];
+ }
+
+ if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
+ xmask |= StructureNotifyMask | PropertyChangeMask;
+
+ XSelectInput (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ xmask);
+}
+++ /dev/null
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gdkdevice-core.h"
-
-#include "gdkinternals.h"
-#include "gdkwindow.h"
-#include "gdkprivate-x11.h"
-#include "gdkasync.h"
-
-static gboolean gdk_device_core_get_history (GdkDevice *device,
- GdkWindow *window,
- guint32 start,
- guint32 stop,
- GdkTimeCoord ***events,
- gint *n_events);
-static void gdk_device_core_get_state (GdkDevice *device,
- GdkWindow *window,
- gdouble *axes,
- GdkModifierType *mask);
-static void gdk_device_core_set_window_cursor (GdkDevice *device,
- GdkWindow *window,
- GdkCursor *cursor);
-static void gdk_device_core_warp (GdkDevice *device,
- GdkScreen *screen,
- gint x,
- gint y);
-static gboolean gdk_device_core_query_state (GdkDevice *device,
- GdkWindow *window,
- GdkWindow **root_window,
- GdkWindow **child_window,
- gint *root_x,
- gint *root_y,
- gint *win_x,
- gint *win_y,
- GdkModifierType *mask);
-static GdkGrabStatus gdk_device_core_grab (GdkDevice *device,
- GdkWindow *window,
- gboolean owner_events,
- GdkEventMask event_mask,
- GdkWindow *confine_to,
- GdkCursor *cursor,
- guint32 time_);
-static void gdk_device_core_ungrab (GdkDevice *device,
- guint32 time_);
-static GdkWindow * gdk_device_core_window_at_position (GdkDevice *device,
- gint *win_x,
- gint *win_y,
- GdkModifierType *mask,
- gboolean get_toplevel);
-static void gdk_device_core_select_window_events (GdkDevice *device,
- GdkWindow *window,
- GdkEventMask event_mask);
-
-
-G_DEFINE_TYPE (GdkDeviceCore, gdk_device_core, GDK_TYPE_DEVICE)
-
-static void
-gdk_device_core_class_init (GdkDeviceCoreClass *klass)
-{
- GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
-
- device_class->get_history = gdk_device_core_get_history;
- device_class->get_state = gdk_device_core_get_state;
- device_class->set_window_cursor = gdk_device_core_set_window_cursor;
- device_class->warp = gdk_device_core_warp;
- device_class->query_state = gdk_device_core_query_state;
- device_class->grab = gdk_device_core_grab;
- device_class->ungrab = gdk_device_core_ungrab;
- device_class->window_at_position = gdk_device_core_window_at_position;
- device_class->select_window_events = gdk_device_core_select_window_events;
-}
-
-static void
-gdk_device_core_init (GdkDeviceCore *device_core)
-{
- GdkDevice *device;
-
- device = GDK_DEVICE (device_core);
-
- _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_X, 0, 0, 1);
- _gdk_device_add_axis (device, GDK_NONE, GDK_AXIS_Y, 0, 0, 1);
-}
-
-static gboolean
-impl_coord_in_window (GdkWindow *window,
- int impl_x,
- int impl_y)
-{
- if (impl_x < window->abs_x ||
- impl_x >= window->abs_x + window->width)
- return FALSE;
-
- if (impl_y < window->abs_y ||
- impl_y >= window->abs_y + window->height)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-gdk_device_core_get_history (GdkDevice *device,
- GdkWindow *window,
- guint32 start,
- guint32 stop,
- GdkTimeCoord ***events,
- gint *n_events)
-{
- XTimeCoord *xcoords;
- GdkTimeCoord **coords;
- GdkWindow *impl_window;
- int tmp_n_events;
- int i, j;
-
- impl_window = _gdk_window_get_impl_window (window);
- xcoords = XGetMotionEvents (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (impl_window),
- start, stop, &tmp_n_events);
- if (!xcoords)
- return FALSE;
-
- coords = _gdk_device_allocate_history (device, tmp_n_events);
-
- for (i = 0, j = 0; i < tmp_n_events; i++)
- {
- if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
- {
- coords[j]->time = xcoords[i].time;
- coords[j]->axes[0] = xcoords[i].x - window->abs_x;
- coords[j]->axes[1] = xcoords[i].y - window->abs_y;
- j++;
- }
- }
-
- XFree (xcoords);
-
- /* free the events we allocated too much */
- for (i = j; i < tmp_n_events; i++)
- {
- g_free (coords[i]);
- coords[i] = NULL;
- }
-
- tmp_n_events = j;
-
- if (tmp_n_events == 0)
- {
- gdk_device_free_history (coords, tmp_n_events);
- return FALSE;
- }
-
- if (n_events)
- *n_events = tmp_n_events;
-
- if (events)
- *events = coords;
- else if (coords)
- gdk_device_free_history (coords, tmp_n_events);
-
- return TRUE;
-}
-
-static void
-gdk_device_core_get_state (GdkDevice *device,
- GdkWindow *window,
- gdouble *axes,
- GdkModifierType *mask)
-{
- gint x_int, y_int;
-
- gdk_window_get_pointer (window, &x_int, &y_int, mask);
-
- if (axes)
- {
- axes[0] = x_int;
- axes[1] = y_int;
- }
-}
-
-static void
-gdk_device_core_set_window_cursor (GdkDevice *device,
- GdkWindow *window,
- GdkCursor *cursor)
-{
- Cursor xcursor;
-
- if (!cursor)
- xcursor = None;
- else
- xcursor = gdk_x11_cursor_get_xcursor (cursor);
-
- XDefineCursor (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- xcursor);
-}
-
-static void
-gdk_device_core_warp (GdkDevice *device,
- GdkScreen *screen,
- gint x,
- gint y)
-{
- Display *xdisplay;
- Window dest;
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gdk_device_get_display (device));
- dest = GDK_WINDOW_XID (gdk_screen_get_root_window (screen));
-
- XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
-}
-
-static gboolean
-gdk_device_core_query_state (GdkDevice *device,
- GdkWindow *window,
- GdkWindow **root_window,
- GdkWindow **child_window,
- gint *root_x,
- gint *root_y,
- gint *win_x,
- gint *win_y,
- GdkModifierType *mask)
-{
- GdkDisplay *display;
- GdkScreen *default_screen;
- Window xroot_window, xchild_window;
- int xroot_x, xroot_y, xwin_x, xwin_y;
- unsigned int xmask;
-
- display = gdk_window_get_display (window);
- default_screen = gdk_display_get_default_screen (display);
-
- if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
- {
- if (!XQueryPointer (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- &xroot_window,
- &xchild_window,
- &xroot_x,
- &xroot_y,
- &xwin_x,
- &xwin_y,
- &xmask))
- return FALSE;
- }
- else
- {
- XSetWindowAttributes attributes;
- Display *xdisplay;
- Window xwindow, w;
-
- /* FIXME: untrusted clients not multidevice-safe */
- xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
- xwindow = GDK_SCREEN_XROOTWIN (default_screen);
-
- w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
- CopyFromParent, InputOnly, CopyFromParent,
- 0, &attributes);
- XQueryPointer (xdisplay, w,
- &xroot_window,
- &xchild_window,
- &xroot_x,
- &xroot_y,
- &xwin_x,
- &xwin_y,
- &xmask);
- XDestroyWindow (xdisplay, w);
- }
-
- if (root_window)
- *root_window = gdk_x11_window_lookup_for_display (display, xroot_window);
-
- if (child_window)
- *child_window = gdk_x11_window_lookup_for_display (display, xchild_window);
-
- if (root_x)
- *root_x = xroot_x;
-
- if (root_y)
- *root_y = xroot_y;
-
- if (win_x)
- *win_x = xwin_x;
-
- if (win_y)
- *win_y = xwin_y;
-
- if (mask)
- *mask = xmask;
-
- return TRUE;
-}
-
-static GdkGrabStatus
-gdk_device_core_grab (GdkDevice *device,
- GdkWindow *window,
- gboolean owner_events,
- GdkEventMask event_mask,
- GdkWindow *confine_to,
- GdkCursor *cursor,
- guint32 time_)
-{
- GdkDisplay *display;
- Window xwindow, xconfine_to;
- gint status;
-
- display = gdk_device_get_display (device);
-
- xwindow = GDK_WINDOW_XID (window);
-
- if (confine_to)
- confine_to = _gdk_window_get_impl_window (confine_to);
-
- if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
- xconfine_to = None;
- else
- xconfine_to = GDK_WINDOW_XID (confine_to);
-
-#ifdef G_ENABLE_DEBUG
- if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
- status = GrabSuccess;
- else
-#endif
- if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
- {
- /* Device is a keyboard */
- status = XGrabKeyboard (GDK_DISPLAY_XDISPLAY (display),
- xwindow,
- owner_events,
- GrabModeAsync, GrabModeAsync,
- time_);
- }
- else
- {
- Cursor xcursor;
- guint xevent_mask;
- gint i;
-
- /* Device is a pointer */
- if (!cursor)
- xcursor = None;
- else
- {
- _gdk_x11_cursor_update_theme (cursor);
- xcursor = gdk_x11_cursor_get_xcursor (cursor);
- }
-
- xevent_mask = 0;
-
- for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
- {
- if (event_mask & (1 << (i + 1)))
- xevent_mask |= _gdk_x11_event_mask_table[i];
- }
-
- /* We don't want to set a native motion hint mask, as we're emulating motion
- * hints. If we set a native one we just wouldn't get any events.
- */
- xevent_mask &= ~PointerMotionHintMask;
-
- status = XGrabPointer (GDK_DISPLAY_XDISPLAY (display),
- xwindow,
- owner_events,
- xevent_mask,
- GrabModeAsync, GrabModeAsync,
- xconfine_to,
- xcursor,
- time_);
- }
-
- _gdk_x11_display_update_grab_info (display, device, status);
-
- return _gdk_x11_convert_grab_status (status);
-}
-
-static void
-gdk_device_core_ungrab (GdkDevice *device,
- guint32 time_)
-{
- GdkDisplay *display;
- gulong serial;
-
- display = gdk_device_get_display (device);
- serial = NextRequest (GDK_DISPLAY_XDISPLAY (display));
-
- if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
- XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_);
- else
- XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_);
-
- _gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial);
-}
-
-static GdkWindow *
-gdk_device_core_window_at_position (GdkDevice *device,
- gint *win_x,
- gint *win_y,
- GdkModifierType *mask,
- gboolean get_toplevel)
-{
- GdkDisplay *display;
- GdkScreen *screen;
- Display *xdisplay;
- GdkWindow *window;
- Window xwindow, root, child, last;
- int xroot_x, xroot_y, xwin_x, xwin_y;
- unsigned int xmask;
-
- last = None;
- display = gdk_device_get_display (device);
- screen = gdk_display_get_default_screen (display);
-
- /* This function really only works if the mouse pointer is held still
- * during its operation. If it moves from one leaf window to another
- * than we'll end up with inaccurate values for win_x, win_y
- * and the result.
- */
- gdk_x11_display_grab (display);
-
- xdisplay = GDK_SCREEN_XDISPLAY (screen);
- xwindow = GDK_SCREEN_XROOTWIN (screen);
-
- if (G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client))
- {
- XQueryPointer (xdisplay, xwindow,
- &root, &child,
- &xroot_x, &xroot_y,
- &xwin_x, &xwin_y,
- &xmask);
-
- if (root == xwindow)
- xwindow = child;
- else
- xwindow = root;
- }
- else
- {
- gint i, screens, width, height;
- GList *toplevels, *list;
- Window pointer_window, root, child;
- int rootx = -1, rooty = -1;
- int winx, winy;
- unsigned int xmask;
-
- /* FIXME: untrusted clients case not multidevice-safe */
- pointer_window = None;
- screens = gdk_display_get_n_screens (display);
-
- for (i = 0; i < screens; ++i)
- {
- screen = gdk_display_get_screen (display, i);
- toplevels = gdk_screen_get_toplevel_windows (screen);
- for (list = toplevels; list != NULL; list = g_list_next (list))
- {
- window = GDK_WINDOW (list->data);
- xwindow = GDK_WINDOW_XID (window);
- gdk_x11_display_error_trap_push (display);
- XQueryPointer (xdisplay, xwindow,
- &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
- if (gdk_x11_display_error_trap_pop (display))
- continue;
- if (child != None)
- {
- pointer_window = child;
- break;
- }
- gdk_window_get_geometry (window, NULL, NULL, &width, &height);
- if (winx >= 0 && winy >= 0 && winx < width && winy < height)
- {
- /* A childless toplevel, or below another window? */
- XSetWindowAttributes attributes;
- Window w;
-
- w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
- CopyFromParent, InputOnly, CopyFromParent,
- 0, &attributes);
- XMapWindow (xdisplay, w);
- XQueryPointer (xdisplay, xwindow,
- &root, &child,
- &rootx, &rooty, &winx, &winy, &xmask);
- XDestroyWindow (xdisplay, w);
- if (child == w)
- {
- pointer_window = xwindow;
- break;
- }
- }
- }
-
- g_list_free (toplevels);
- if (pointer_window != None)
- break;
- }
-
- xwindow = pointer_window;
- }
-
- while (xwindow)
- {
- last = xwindow;
- gdk_x11_display_error_trap_push (display);
- XQueryPointer (xdisplay, xwindow,
- &root, &xwindow,
- &xroot_x, &xroot_y,
- &xwin_x, &xwin_y,
- &xmask);
- if (gdk_x11_display_error_trap_pop (display))
- break;
-
- if (get_toplevel && last != root &&
- (window = gdk_x11_window_lookup_for_display (display, last)) != NULL &&
- window->window_type != GDK_WINDOW_FOREIGN)
- {
- xwindow = last;
- break;
- }
- }
-
- gdk_x11_display_ungrab (display);
-
- window = gdk_x11_window_lookup_for_display (display, last);
-
- if (win_x)
- *win_x = (window) ? xwin_x : -1;
-
- if (win_y)
- *win_y = (window) ? xwin_y : -1;
-
- if (mask)
- *mask = xmask;
-
- return window;
-}
-
-static void
-gdk_device_core_select_window_events (GdkDevice *device,
- GdkWindow *window,
- GdkEventMask event_mask)
-{
- GdkEventMask filter_mask, window_mask;
- guint xmask = 0;
- gint i;
-
- window_mask = gdk_window_get_events (window);
- filter_mask = (GDK_POINTER_MOTION_MASK &
- GDK_POINTER_MOTION_HINT_MASK &
- GDK_BUTTON_MOTION_MASK &
- GDK_BUTTON1_MOTION_MASK &
- GDK_BUTTON2_MOTION_MASK &
- GDK_BUTTON3_MOTION_MASK &
- GDK_BUTTON_PRESS_MASK &
- GDK_BUTTON_RELEASE_MASK &
- GDK_KEY_PRESS_MASK &
- GDK_KEY_RELEASE_MASK &
- GDK_ENTER_NOTIFY_MASK &
- GDK_LEAVE_NOTIFY_MASK &
- GDK_FOCUS_CHANGE_MASK &
- GDK_PROXIMITY_IN_MASK &
- GDK_PROXIMITY_OUT_MASK &
- GDK_SCROLL_MASK);
-
- /* Filter out non-device events */
- event_mask &= filter_mask;
-
- /* Unset device events on window mask */
- window_mask &= ~(filter_mask);
-
- /* Combine masks */
- event_mask |= window_mask;
-
- for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
- {
- if (event_mask & (1 << (i + 1)))
- xmask |= _gdk_x11_event_mask_table[i];
- }
-
- if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
- xmask |= StructureNotifyMask | PropertyChangeMask;
-
- XSelectInput (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- xmask);
-}
+++ /dev/null
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GDK_DEVICE_CORE_H__
-#define __GDK_DEVICE_CORE_H__
-
-#include "gdkdeviceprivate.h"
-
-G_BEGIN_DECLS
-
-#define GDK_TYPE_DEVICE_CORE (gdk_device_core_get_type ())
-#define GDK_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCore))
-#define GDK_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
-#define GDK_IS_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_CORE))
-#define GDK_IS_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_CORE))
-#define GDK_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_CORE, GdkDeviceCoreClass))
-
-typedef struct _GdkDeviceCore GdkDeviceCore;
-typedef struct _GdkDeviceCoreClass GdkDeviceCoreClass;
-
-struct _GdkDeviceCore
-{
- GdkDevice parent_instance;
-};
-
-struct _GdkDeviceCoreClass
-{
- GdkDeviceClass parent_class;
-};
-
-G_GNUC_INTERNAL
-GType gdk_device_core_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* __GDK_DEVICE_CORE_H__ */
--- /dev/null
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdkx11devicemanager-core.h"
+#include "gdkx11device-core.h"
+
+#include "gdkkeysyms.h"
+#include "gdkdevicemanagerprivate.h"
+#include "gdkdisplayprivate.h"
+#include "gdkeventtranslator.h"
+#include "gdkprivate-x11.h"
+
+#ifdef HAVE_XKB
+#include <X11/XKBlib.h>
+#endif
+
+
+#define HAS_FOCUS(toplevel) \
+ ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
+
+static void gdk_x11_device_manager_core_finalize (GObject *object);
+static void gdk_x11_device_manager_core_constructed (GObject *object);
+
+static GList * gdk_x11_device_manager_core_list_devices (GdkDeviceManager *device_manager,
+ GdkDeviceType type);
+static GdkDevice * gdk_x11_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager);
+
+static void gdk_x11_device_manager_event_translator_init (GdkEventTranslatorIface *iface);
+
+static gboolean gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
+ GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent);
+
+
+G_DEFINE_TYPE_WITH_CODE (GdkX11DeviceManagerCore, gdk_x11_device_manager_core, GDK_TYPE_DEVICE_MANAGER,
+ G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
+ gdk_x11_device_manager_event_translator_init))
+
+static void
+gdk_x11_device_manager_core_class_init (GdkX11DeviceManagerCoreClass *klass)
+{
+ GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gdk_x11_device_manager_core_finalize;
+ object_class->constructed = gdk_x11_device_manager_core_constructed;
+ device_manager_class->list_devices = gdk_x11_device_manager_core_list_devices;
+ device_manager_class->get_client_pointer = gdk_x11_device_manager_core_get_client_pointer;
+}
+
+static void
+gdk_x11_device_manager_event_translator_init (GdkEventTranslatorIface *iface)
+{
+ iface->translate_event = gdk_x11_device_manager_core_translate_event;
+}
+
+static GdkDevice *
+create_core_pointer (GdkDeviceManager *device_manager,
+ GdkDisplay *display)
+{
+ return g_object_new (GDK_TYPE_X11_DEVICE_CORE,
+ "name", "Core Pointer",
+ "type", GDK_DEVICE_TYPE_MASTER,
+ "input-source", GDK_SOURCE_MOUSE,
+ "input-mode", GDK_MODE_SCREEN,
+ "has-cursor", TRUE,
+ "display", display,
+ "device-manager", device_manager,
+ NULL);
+}
+
+static GdkDevice *
+create_core_keyboard (GdkDeviceManager *device_manager,
+ GdkDisplay *display)
+{
+ return g_object_new (GDK_TYPE_X11_DEVICE_CORE,
+ "name", "Core Keyboard",
+ "type", GDK_DEVICE_TYPE_MASTER,
+ "input-source", GDK_SOURCE_KEYBOARD,
+ "input-mode", GDK_MODE_SCREEN,
+ "has-cursor", FALSE,
+ "display", display,
+ "device-manager", device_manager,
+ NULL);
+}
+
+static void
+gdk_x11_device_manager_core_init (GdkX11DeviceManagerCore *device_manager)
+{
+}
+
+static void
+gdk_x11_device_manager_core_finalize (GObject *object)
+{
+ GdkX11DeviceManagerCore *device_manager_core;
+
+ device_manager_core = GDK_X11_DEVICE_MANAGER_CORE (object);
+
+ g_object_unref (device_manager_core->core_pointer);
+ g_object_unref (device_manager_core->core_keyboard);
+
+ G_OBJECT_CLASS (gdk_x11_device_manager_core_parent_class)->finalize (object);
+}
+
+static void
+gdk_x11_device_manager_core_constructed (GObject *object)
+{
+ GdkX11DeviceManagerCore *device_manager;
+ GdkDisplay *display;
+
+ device_manager = GDK_X11_DEVICE_MANAGER_CORE (object);
+ display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
+ device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
+ device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
+
+ _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
+ _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
+}
+
+static void
+translate_key_event (GdkDisplay *display,
+ GdkX11DeviceManagerCore *device_manager,
+ GdkEvent *event,
+ XEvent *xevent)
+{
+ GdkKeymap *keymap = gdk_keymap_get_for_display (display);
+ GdkModifierType consumed, state;
+ gunichar c = 0;
+ gchar buf[7];
+
+ event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
+ event->key.time = xevent->xkey.time;
+ gdk_event_set_device (event, device_manager->core_keyboard);
+
+ event->key.state = (GdkModifierType) xevent->xkey.state;
+ event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
+ event->key.hardware_keycode = xevent->xkey.keycode;
+
+ event->key.keyval = GDK_KEY_VoidSymbol;
+
+ gdk_keymap_translate_keyboard_state (keymap,
+ event->key.hardware_keycode,
+ event->key.state,
+ event->key.group,
+ &event->key.keyval,
+ NULL, NULL, &consumed);
+
+ state = event->key.state & ~consumed;
+ _gdk_x11_keymap_add_virt_mods (keymap, &state);
+ event->key.state |= state;
+
+ event->key.is_modifier = _gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
+
+ /* Fill in event->string crudely, since various programs
+ * depend on it.
+ */
+ event->key.string = NULL;
+
+ if (event->key.keyval != GDK_KEY_VoidSymbol)
+ c = gdk_keyval_to_unicode (event->key.keyval);
+
+ if (c)
+ {
+ gsize bytes_written;
+ gint len;
+
+ /* Apply the control key - Taken from Xlib
+ */
+ if (event->key.state & GDK_CONTROL_MASK)
+ {
+ if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
+ else if (c == '2')
+ {
+ event->key.string = g_memdup ("\0\0", 2);
+ event->key.length = 1;
+ buf[0] = '\0';
+ goto out;
+ }
+ else if (c >= '3' && c <= '7') c -= ('3' - '\033');
+ else if (c == '8') c = '\177';
+ else if (c == '/') c = '_' & 0x1F;
+ }
+
+ len = g_unichar_to_utf8 (c, buf);
+ buf[len] = '\0';
+
+ event->key.string = g_locale_from_utf8 (buf, len,
+ NULL, &bytes_written,
+ NULL);
+ if (event->key.string)
+ event->key.length = bytes_written;
+ }
+ else if (event->key.keyval == GDK_KEY_Escape)
+ {
+ event->key.length = 1;
+ event->key.string = g_strdup ("\033");
+ }
+ else if (event->key.keyval == GDK_KEY_Return ||
+ event->key.keyval == GDK_KEY_KP_Enter)
+ {
+ event->key.length = 1;
+ event->key.string = g_strdup ("\r");
+ }
+
+ if (!event->key.string)
+ {
+ event->key.length = 0;
+ event->key.string = g_strdup ("");
+ }
+
+ out:
+#ifdef G_ENABLE_DEBUG
+ if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
+ {
+ g_message ("%s:\t\twindow: %ld key: %12s %d",
+ event->type == GDK_KEY_PRESS ? "key press " : "key release",
+ xevent->xkey.window,
+ event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
+ event->key.keyval);
+
+ if (event->key.length > 0)
+ g_message ("\t\tlength: %4d string: \"%s\"",
+ event->key.length, buf);
+ }
+#endif /* G_ENABLE_DEBUG */
+ return;
+}
+
+#ifdef G_ENABLE_DEBUG
+static const char notify_modes[][19] = {
+ "NotifyNormal",
+ "NotifyGrab",
+ "NotifyUngrab",
+ "NotifyWhileGrabbed"
+};
+
+static const char notify_details[][23] = {
+ "NotifyAncestor",
+ "NotifyVirtual",
+ "NotifyInferior",
+ "NotifyNonlinear",
+ "NotifyNonlinearVirtual",
+ "NotifyPointer",
+ "NotifyPointerRoot",
+ "NotifyDetailNone"
+};
+#endif
+
+static void
+set_user_time (GdkWindow *window,
+ GdkEvent *event)
+{
+ g_return_if_fail (event != NULL);
+
+ window = gdk_window_get_toplevel (event->client.window);
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ /* If an event doesn't have a valid timestamp, we shouldn't use it
+ * to update the latest user interaction time.
+ */
+ if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
+ gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
+}
+
+static void
+generate_focus_event (GdkX11DeviceManagerCore *device_manager,
+ GdkWindow *window,
+ gboolean in)
+{
+ GdkEvent *event;
+
+ event = gdk_event_new (GDK_FOCUS_CHANGE);
+ event->focus_change.window = g_object_ref (window);
+ event->focus_change.send_event = FALSE;
+ event->focus_change.in = in;
+ gdk_event_set_device (event, device_manager->core_keyboard);
+
+ gdk_event_put (event);
+ gdk_event_free (event);
+}
+
+static gboolean
+set_screen_from_root (GdkDisplay *display,
+ GdkEvent *event,
+ Window xrootwin)
+{
+ GdkScreen *screen;
+
+ screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
+
+ if (screen)
+ {
+ gdk_event_set_screen (event, screen);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static GdkCrossingMode
+translate_crossing_mode (int mode)
+{
+ switch (mode)
+ {
+ case NotifyNormal:
+ return GDK_CROSSING_NORMAL;
+ case NotifyGrab:
+ return GDK_CROSSING_GRAB;
+ case NotifyUngrab:
+ return GDK_CROSSING_UNGRAB;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static GdkNotifyType
+translate_notify_type (int detail)
+{
+ switch (detail)
+ {
+ case NotifyInferior:
+ return GDK_NOTIFY_INFERIOR;
+ case NotifyAncestor:
+ return GDK_NOTIFY_ANCESTOR;
+ case NotifyVirtual:
+ return GDK_NOTIFY_VIRTUAL;
+ case NotifyNonlinear:
+ return GDK_NOTIFY_NONLINEAR;
+ case NotifyNonlinearVirtual:
+ return GDK_NOTIFY_NONLINEAR_VIRTUAL;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gboolean
+is_parent_of (GdkWindow *parent,
+ GdkWindow *child)
+{
+ GdkWindow *w;
+
+ w = child;
+ while (w != NULL)
+ {
+ if (w == parent)
+ return TRUE;
+
+ w = gdk_window_get_parent (w);
+ }
+
+ return FALSE;
+}
+
+static GdkWindow *
+get_event_window (GdkEventTranslator *translator,
+ XEvent *xevent)
+{
+ GdkDeviceManager *device_manager;
+ GdkDisplay *display;
+ GdkWindow *window;
+
+ device_manager = GDK_DEVICE_MANAGER (translator);
+ display = gdk_device_manager_get_display (device_manager);
+ window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);
+
+ /* Apply keyboard grabs to non-native windows */
+ if (xevent->type == KeyPress || xevent->type == KeyRelease)
+ {
+ GdkDeviceGrabInfo *info;
+ gulong serial;
+
+ serial = _gdk_display_get_next_serial (display);
+ info = _gdk_display_has_device_grab (display,
+ GDK_X11_DEVICE_MANAGER_CORE (device_manager)->core_keyboard,
+ serial);
+ if (info &&
+ (!is_parent_of (info->window, window) ||
+ !info->owner_events))
+ {
+ /* Report key event against grab window */
+ window = info->window;
+ }
+ }
+
+ return window;
+}
+
+static gboolean
+gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
+ GdkDisplay *display,
+ GdkEvent *event,
+ XEvent *xevent)
+{
+ GdkX11DeviceManagerCore *device_manager;
+ GdkWindow *window;
+ GdkWindowImplX11 *window_impl = NULL;
+ gboolean return_val;
+ GdkToplevelX11 *toplevel = NULL;
+ GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+
+ device_manager = GDK_X11_DEVICE_MANAGER_CORE (translator);
+ return_val = FALSE;
+
+ window = get_event_window (translator, xevent);
+
+ if (window)
+ {
+ if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window))
+ return FALSE;
+
+ toplevel = _gdk_x11_window_get_toplevel (window);
+ window_impl = GDK_WINDOW_IMPL_X11 (window->impl);
+ g_object_ref (window);
+ }
+
+ event->any.window = window;
+ event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
+
+ if (window && GDK_WINDOW_DESTROYED (window))
+ {
+ if (xevent->type != DestroyNotify)
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+
+ if (window &&
+ (xevent->type == MotionNotify ||
+ xevent->type == ButtonRelease))
+ {
+ if (_gdk_x11_moveresize_handle_event (xevent))
+ {
+ return_val = FALSE;
+ goto done;
+ }
+ }
+
+ /* We do a "manual" conversion of the XEvent to a
+ * GdkEvent. The structures are mostly the same so
+ * the conversion is fairly straightforward. We also
+ * optionally print debugging info regarding events
+ * received.
+ */
+
+ return_val = TRUE;
+
+ switch (xevent->type)
+ {
+ case KeyPress:
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+ translate_key_event (display, device_manager, event, xevent);
+ set_user_time (window, event);
+ break;
+
+ case KeyRelease:
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* Emulate detectable auto-repeat by checking to see
+ * if the next event is a key press with the same
+ * keycode and timestamp, and if so, ignoring the event.
+ */
+
+ if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
+ {
+ XEvent next_event;
+
+ XPeekEvent (xevent->xkey.display, &next_event);
+
+ if (next_event.type == KeyPress &&
+ next_event.xkey.keycode == xevent->xkey.keycode &&
+ next_event.xkey.time == xevent->xkey.time)
+ {
+ return_val = FALSE;
+ break;
+ }
+ }
+
+ translate_key_event (display, device_manager, event, xevent);
+ break;
+
+ case ButtonPress:
+ GDK_NOTE (EVENTS,
+ g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d",
+ xevent->xbutton.window,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.button));
+
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* If we get a ButtonPress event where the button is 4 or 5,
+ it's a Scroll event */
+ switch (xevent->xbutton.button)
+ {
+ case 4: /* up */
+ case 5: /* down */
+ case 6: /* left */
+ case 7: /* right */
+ event->scroll.type = GDK_SCROLL;
+
+ if (xevent->xbutton.button == 4)
+ event->scroll.direction = GDK_SCROLL_UP;
+ else if (xevent->xbutton.button == 5)
+ event->scroll.direction = GDK_SCROLL_DOWN;
+ else if (xevent->xbutton.button == 6)
+ event->scroll.direction = GDK_SCROLL_LEFT;
+ else
+ event->scroll.direction = GDK_SCROLL_RIGHT;
+
+ event->scroll.window = window;
+ event->scroll.time = xevent->xbutton.time;
+ event->scroll.x = (gdouble) xevent->xbutton.x;
+ event->scroll.y = (gdouble) xevent->xbutton.y;
+ event->scroll.x_root = (gdouble) xevent->xbutton.x_root;
+ event->scroll.y_root = (gdouble) xevent->xbutton.y_root;
+ event->scroll.state = (GdkModifierType) xevent->xbutton.state;
+ event->scroll.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ break;
+
+ default:
+ event->button.type = GDK_BUTTON_PRESS;
+ event->button.window = window;
+ event->button.time = xevent->xbutton.time;
+ event->button.x = (gdouble) xevent->xbutton.x;
+ event->button.y = (gdouble) xevent->xbutton.y;
+ event->button.x_root = (gdouble) xevent->xbutton.x_root;
+ event->button.y_root = (gdouble) xevent->xbutton.y_root;
+ event->button.axes = NULL;
+ event->button.state = (GdkModifierType) xevent->xbutton.state;
+ event->button.button = xevent->xbutton.button;
+ event->button.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ return_val = FALSE;
+
+ break;
+ }
+
+ set_user_time (window, event);
+
+ break;
+
+ case ButtonRelease:
+ GDK_NOTE (EVENTS,
+ g_message ("button release:\twindow: %ld x,y: %d %d button: %d",
+ xevent->xbutton.window,
+ xevent->xbutton.x, xevent->xbutton.y,
+ xevent->xbutton.button));
+
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ /* We treat button presses as scroll wheel events, so ignore the release */
+ if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
+ xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ event->button.type = GDK_BUTTON_RELEASE;
+ event->button.window = window;
+ event->button.time = xevent->xbutton.time;
+ event->button.x = (gdouble) xevent->xbutton.x;
+ event->button.y = (gdouble) xevent->xbutton.y;
+ event->button.x_root = (gdouble) xevent->xbutton.x_root;
+ event->button.y_root = (gdouble) xevent->xbutton.y_root;
+ event->button.axes = NULL;
+ event->button.state = (GdkModifierType) xevent->xbutton.state;
+ event->button.button = xevent->xbutton.button;
+ event->button.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ return_val = FALSE;
+
+ break;
+
+ case MotionNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s",
+ xevent->xmotion.window,
+ xevent->xmotion.x, xevent->xmotion.y,
+ (xevent->xmotion.is_hint) ? "true" : "false"));
+
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ event->motion.type = GDK_MOTION_NOTIFY;
+ event->motion.window = window;
+ event->motion.time = xevent->xmotion.time;
+ event->motion.x = (gdouble) xevent->xmotion.x;
+ event->motion.y = (gdouble) xevent->xmotion.y;
+ event->motion.x_root = (gdouble) xevent->xmotion.x_root;
+ event->motion.y_root = (gdouble) xevent->xmotion.y_root;
+ event->motion.axes = NULL;
+ event->motion.state = (GdkModifierType) xevent->xmotion.state;
+ event->motion.is_hint = xevent->xmotion.is_hint;
+ event->motion.device = device_manager->core_pointer;
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ break;
+
+ case EnterNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld",
+ xevent->xcrossing.window,
+ xevent->xcrossing.detail,
+ xevent->xcrossing.subwindow));
+
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ event->crossing.type = GDK_ENTER_NOTIFY;
+ event->crossing.window = window;
+ gdk_event_set_device (event, device_manager->core_pointer);
+
+ /* If the subwindow field of the XEvent is non-NULL, then
+ * lookup the corresponding GdkWindow.
+ */
+ if (xevent->xcrossing.subwindow != None)
+ event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
+ else
+ event->crossing.subwindow = NULL;
+
+ event->crossing.time = xevent->xcrossing.time;
+ event->crossing.x = (gdouble) xevent->xcrossing.x;
+ event->crossing.y = (gdouble) xevent->xcrossing.y;
+ event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
+ event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
+
+ event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
+ event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
+
+ event->crossing.focus = xevent->xcrossing.focus;
+ event->crossing.state = xevent->xcrossing.state;
+
+ break;
+
+ case LeaveNotify:
+ GDK_NOTE (EVENTS,
+ g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld",
+ xevent->xcrossing.window,
+ xevent->xcrossing.detail, xevent->xcrossing.subwindow));
+
+ if (window == NULL)
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ if (!set_screen_from_root (display, event, xevent->xbutton.root))
+ {
+ return_val = FALSE;
+ break;
+ }
+
+ event->crossing.type = GDK_LEAVE_NOTIFY;
+ event->crossing.window = window;
+ gdk_event_set_device (event, device_manager->core_pointer);
+
+ /* If the subwindow field of the XEvent is non-NULL, then
+ * lookup the corresponding GdkWindow.
+ */
+ if (xevent->xcrossing.subwindow != None)
+ event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
+ else
+ event->crossing.subwindow = NULL;
+
+ event->crossing.time = xevent->xcrossing.time;
+ event->crossing.x = (gdouble) xevent->xcrossing.x;
+ event->crossing.y = (gdouble) xevent->xcrossing.y;
+ event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
+ event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
+
+ event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
+ event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
+
+ event->crossing.focus = xevent->xcrossing.focus;
+ event->crossing.state = xevent->xcrossing.state;
+
+ break;
+
+ /* We only care about focus events that indicate that _this_
+ * window (not a ancestor or child) got or lost the focus
+ */
+ case FocusIn:
+ GDK_NOTE (EVENTS,
+ g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
+
+ if (toplevel)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ switch (xevent->xfocus.detail)
+ {
+ case NotifyAncestor:
+ case NotifyVirtual:
+ /* When the focus moves from an ancestor of the window to
+ * the window or a descendent of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_pointer_focus
+ * case and are now receiving them in the
+ * has_focus_window case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
+
+ /* fall through */
+ case NotifyNonlinear:
+ case NotifyNonlinearVirtual:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = TRUE;
+ /* We pretend that the focus moves to the grab
+ * window, so we pay attention to NotifyGrab
+ * NotifyUngrab, and ignore NotifyWhileGrabbed
+ */
+ if (xevent->xfocus.mode != NotifyWhileGrabbed)
+ toplevel->has_focus = TRUE;
+ break;
+ case NotifyPointer:
+ /* The X server sends NotifyPointer/NotifyGrab,
+ * but the pointer focus is ignored while a
+ * grab is in effect
+ */
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = TRUE;
+ break;
+ case NotifyInferior:
+ case NotifyPointerRoot:
+ case NotifyDetailNone:
+ break;
+ }
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (device_manager, window, TRUE);
+ }
+ break;
+ case FocusOut:
+ GDK_NOTE (EVENTS,
+ g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
+ xevent->xfocus.window,
+ notify_details[xevent->xfocus.detail],
+ notify_modes[xevent->xfocus.mode]));
+
+ if (toplevel)
+ {
+ gboolean had_focus = HAS_FOCUS (toplevel);
+
+ switch (xevent->xfocus.detail)
+ {
+ case NotifyAncestor:
+ case NotifyVirtual:
+ /* When the focus moves from the window or a descendent
+ * of the window to an ancestor of the window, *and* the
+ * pointer is inside the window, then we were previously
+ * receiving keystroke events in the has_focus_window
+ * case and are now receiving them in the
+ * has_pointer_focus case.
+ */
+ if (toplevel->has_pointer &&
+ xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = TRUE;
+
+ /* fall through */
+ case NotifyNonlinear:
+ case NotifyNonlinearVirtual:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_focus_window = FALSE;
+ if (xevent->xfocus.mode != NotifyWhileGrabbed)
+ toplevel->has_focus = FALSE;
+ break;
+ case NotifyPointer:
+ if (xevent->xfocus.mode != NotifyGrab &&
+ xevent->xfocus.mode != NotifyUngrab)
+ toplevel->has_pointer_focus = FALSE;
+ break;
+ case NotifyInferior:
+ case NotifyPointerRoot:
+ case NotifyDetailNone:
+ break;
+ }
+
+ if (HAS_FOCUS (toplevel) != had_focus)
+ generate_focus_event (device_manager, window, FALSE);
+ }
+ break;
+
+ default:
+ return_val = FALSE;
+ }
+
+ done:
+ if (return_val)
+ {
+ if (event->any.window)
+ g_object_ref (event->any.window);
+
+ if (((event->any.type == GDK_ENTER_NOTIFY) ||
+ (event->any.type == GDK_LEAVE_NOTIFY)) &&
+ (event->crossing.subwindow != NULL))
+ g_object_ref (event->crossing.subwindow);
+ }
+ else
+ {
+ /* Mark this event as having no resources to be freed */
+ event->any.window = NULL;
+ event->any.type = GDK_NOTHING;
+ }
+
+ if (window)
+ g_object_unref (window);
+
+ return return_val;
+}
+
+static GList *
+gdk_x11_device_manager_core_list_devices (GdkDeviceManager *device_manager,
+ GdkDeviceType type)
+{
+ GdkX11DeviceManagerCore *device_manager_core;
+ GList *devices = NULL;
+
+ if (type == GDK_DEVICE_TYPE_MASTER)
+ {
+ device_manager_core = (GdkX11DeviceManagerCore *) device_manager;
+ devices = g_list_prepend (devices, device_manager_core->core_keyboard);
+ devices = g_list_prepend (devices, device_manager_core->core_pointer);
+ }
+
+ return devices;
+}
+
+static GdkDevice *
+gdk_x11_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager)
+{
+ GdkX11DeviceManagerCore *device_manager_core;
+
+ device_manager_core = (GdkX11DeviceManagerCore *) device_manager;
+ return device_manager_core->core_pointer;
+}
+++ /dev/null
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include "gdkdevicemanager-core.h"
-
-#include "gdkkeysyms.h"
-#include "gdkdevicemanagerprivate.h"
-#include "gdkdisplayprivate.h"
-#include "gdkeventtranslator.h"
-#include "gdkdevice-core.h"
-#include "gdkprivate-x11.h"
-
-#ifdef HAVE_XKB
-#include <X11/XKBlib.h>
-#endif
-
-
-#define HAS_FOCUS(toplevel) \
- ((toplevel)->has_focus || (toplevel)->has_pointer_focus)
-
-static void gdk_device_manager_core_finalize (GObject *object);
-static void gdk_device_manager_core_constructed (GObject *object);
-
-static GList * gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
- GdkDeviceType type);
-static GdkDevice * gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager);
-
-static void gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface);
-
-static gboolean gdk_device_manager_core_translate_event (GdkEventTranslator *translator,
- GdkDisplay *display,
- GdkEvent *event,
- XEvent *xevent);
-
-
-G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerCore, gdk_device_manager_core, GDK_TYPE_DEVICE_MANAGER,
- G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
- gdk_device_manager_event_translator_init))
-
-static void
-gdk_device_manager_core_class_init (GdkDeviceManagerCoreClass *klass)
-{
- GdkDeviceManagerClass *device_manager_class = GDK_DEVICE_MANAGER_CLASS (klass);
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gdk_device_manager_core_finalize;
- object_class->constructed = gdk_device_manager_core_constructed;
- device_manager_class->list_devices = gdk_device_manager_core_list_devices;
- device_manager_class->get_client_pointer = gdk_device_manager_core_get_client_pointer;
-}
-
-static void
-gdk_device_manager_event_translator_init (GdkEventTranslatorIface *iface)
-{
- iface->translate_event = gdk_device_manager_core_translate_event;
-}
-
-static GdkDevice *
-create_core_pointer (GdkDeviceManager *device_manager,
- GdkDisplay *display)
-{
- return g_object_new (GDK_TYPE_DEVICE_CORE,
- "name", "Core Pointer",
- "type", GDK_DEVICE_TYPE_MASTER,
- "input-source", GDK_SOURCE_MOUSE,
- "input-mode", GDK_MODE_SCREEN,
- "has-cursor", TRUE,
- "display", display,
- "device-manager", device_manager,
- NULL);
-}
-
-static GdkDevice *
-create_core_keyboard (GdkDeviceManager *device_manager,
- GdkDisplay *display)
-{
- return g_object_new (GDK_TYPE_DEVICE_CORE,
- "name", "Core Keyboard",
- "type", GDK_DEVICE_TYPE_MASTER,
- "input-source", GDK_SOURCE_KEYBOARD,
- "input-mode", GDK_MODE_SCREEN,
- "has-cursor", FALSE,
- "display", display,
- "device-manager", device_manager,
- NULL);
-}
-
-static void
-gdk_device_manager_core_init (GdkDeviceManagerCore *device_manager)
-{
-}
-
-static void
-gdk_device_manager_core_finalize (GObject *object)
-{
- GdkDeviceManagerCore *device_manager_core;
-
- device_manager_core = GDK_DEVICE_MANAGER_CORE (object);
-
- g_object_unref (device_manager_core->core_pointer);
- g_object_unref (device_manager_core->core_keyboard);
-
- G_OBJECT_CLASS (gdk_device_manager_core_parent_class)->finalize (object);
-}
-
-static void
-gdk_device_manager_core_constructed (GObject *object)
-{
- GdkDeviceManagerCore *device_manager;
- GdkDisplay *display;
-
- device_manager = GDK_DEVICE_MANAGER_CORE (object);
- display = gdk_device_manager_get_display (GDK_DEVICE_MANAGER (object));
- device_manager->core_pointer = create_core_pointer (GDK_DEVICE_MANAGER (device_manager), display);
- device_manager->core_keyboard = create_core_keyboard (GDK_DEVICE_MANAGER (device_manager), display);
-
- _gdk_device_set_associated_device (device_manager->core_pointer, device_manager->core_keyboard);
- _gdk_device_set_associated_device (device_manager->core_keyboard, device_manager->core_pointer);
-}
-
-static void
-translate_key_event (GdkDisplay *display,
- GdkDeviceManagerCore *device_manager,
- GdkEvent *event,
- XEvent *xevent)
-{
- GdkKeymap *keymap = gdk_keymap_get_for_display (display);
- GdkModifierType consumed, state;
- gunichar c = 0;
- gchar buf[7];
-
- event->key.type = xevent->xany.type == KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
- event->key.time = xevent->xkey.time;
- gdk_event_set_device (event, device_manager->core_keyboard);
-
- event->key.state = (GdkModifierType) xevent->xkey.state;
- event->key.group = _gdk_x11_get_group_for_state (display, xevent->xkey.state);
- event->key.hardware_keycode = xevent->xkey.keycode;
-
- event->key.keyval = GDK_KEY_VoidSymbol;
-
- gdk_keymap_translate_keyboard_state (keymap,
- event->key.hardware_keycode,
- event->key.state,
- event->key.group,
- &event->key.keyval,
- NULL, NULL, &consumed);
-
- state = event->key.state & ~consumed;
- _gdk_x11_keymap_add_virt_mods (keymap, &state);
- event->key.state |= state;
-
- event->key.is_modifier = _gdk_x11_keymap_key_is_modifier (keymap, event->key.hardware_keycode);
-
- /* Fill in event->string crudely, since various programs
- * depend on it.
- */
- event->key.string = NULL;
-
- if (event->key.keyval != GDK_KEY_VoidSymbol)
- c = gdk_keyval_to_unicode (event->key.keyval);
-
- if (c)
- {
- gsize bytes_written;
- gint len;
-
- /* Apply the control key - Taken from Xlib
- */
- if (event->key.state & GDK_CONTROL_MASK)
- {
- if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
- else if (c == '2')
- {
- event->key.string = g_memdup ("\0\0", 2);
- event->key.length = 1;
- buf[0] = '\0';
- goto out;
- }
- else if (c >= '3' && c <= '7') c -= ('3' - '\033');
- else if (c == '8') c = '\177';
- else if (c == '/') c = '_' & 0x1F;
- }
-
- len = g_unichar_to_utf8 (c, buf);
- buf[len] = '\0';
-
- event->key.string = g_locale_from_utf8 (buf, len,
- NULL, &bytes_written,
- NULL);
- if (event->key.string)
- event->key.length = bytes_written;
- }
- else if (event->key.keyval == GDK_KEY_Escape)
- {
- event->key.length = 1;
- event->key.string = g_strdup ("\033");
- }
- else if (event->key.keyval == GDK_KEY_Return ||
- event->key.keyval == GDK_KEY_KP_Enter)
- {
- event->key.length = 1;
- event->key.string = g_strdup ("\r");
- }
-
- if (!event->key.string)
- {
- event->key.length = 0;
- event->key.string = g_strdup ("");
- }
-
- out:
-#ifdef G_ENABLE_DEBUG
- if (_gdk_debug_flags & GDK_DEBUG_EVENTS)
- {
- g_message ("%s:\t\twindow: %ld key: %12s %d",
- event->type == GDK_KEY_PRESS ? "key press " : "key release",
- xevent->xkey.window,
- event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
- event->key.keyval);
-
- if (event->key.length > 0)
- g_message ("\t\tlength: %4d string: \"%s\"",
- event->key.length, buf);
- }
-#endif /* G_ENABLE_DEBUG */
- return;
-}
-
-#ifdef G_ENABLE_DEBUG
-static const char notify_modes[][19] = {
- "NotifyNormal",
- "NotifyGrab",
- "NotifyUngrab",
- "NotifyWhileGrabbed"
-};
-
-static const char notify_details[][23] = {
- "NotifyAncestor",
- "NotifyVirtual",
- "NotifyInferior",
- "NotifyNonlinear",
- "NotifyNonlinearVirtual",
- "NotifyPointer",
- "NotifyPointerRoot",
- "NotifyDetailNone"
-};
-#endif
-
-static void
-set_user_time (GdkWindow *window,
- GdkEvent *event)
-{
- g_return_if_fail (event != NULL);
-
- window = gdk_window_get_toplevel (event->client.window);
- g_return_if_fail (GDK_IS_WINDOW (window));
-
- /* If an event doesn't have a valid timestamp, we shouldn't use it
- * to update the latest user interaction time.
- */
- if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
- gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
- gdk_event_get_time (event));
-}
-
-static void
-generate_focus_event (GdkDeviceManagerCore *device_manager,
- GdkWindow *window,
- gboolean in)
-{
- GdkEvent *event;
-
- event = gdk_event_new (GDK_FOCUS_CHANGE);
- event->focus_change.window = g_object_ref (window);
- event->focus_change.send_event = FALSE;
- event->focus_change.in = in;
- gdk_event_set_device (event, device_manager->core_keyboard);
-
- gdk_event_put (event);
- gdk_event_free (event);
-}
-
-static gboolean
-set_screen_from_root (GdkDisplay *display,
- GdkEvent *event,
- Window xrootwin)
-{
- GdkScreen *screen;
-
- screen = _gdk_x11_display_screen_for_xrootwin (display, xrootwin);
-
- if (screen)
- {
- gdk_event_set_screen (event, screen);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static GdkCrossingMode
-translate_crossing_mode (int mode)
-{
- switch (mode)
- {
- case NotifyNormal:
- return GDK_CROSSING_NORMAL;
- case NotifyGrab:
- return GDK_CROSSING_GRAB;
- case NotifyUngrab:
- return GDK_CROSSING_UNGRAB;
- default:
- g_assert_not_reached ();
- }
-}
-
-static GdkNotifyType
-translate_notify_type (int detail)
-{
- switch (detail)
- {
- case NotifyInferior:
- return GDK_NOTIFY_INFERIOR;
- case NotifyAncestor:
- return GDK_NOTIFY_ANCESTOR;
- case NotifyVirtual:
- return GDK_NOTIFY_VIRTUAL;
- case NotifyNonlinear:
- return GDK_NOTIFY_NONLINEAR;
- case NotifyNonlinearVirtual:
- return GDK_NOTIFY_NONLINEAR_VIRTUAL;
- default:
- g_assert_not_reached ();
- }
-}
-
-static gboolean
-is_parent_of (GdkWindow *parent,
- GdkWindow *child)
-{
- GdkWindow *w;
-
- w = child;
- while (w != NULL)
- {
- if (w == parent)
- return TRUE;
-
- w = gdk_window_get_parent (w);
- }
-
- return FALSE;
-}
-
-static GdkWindow *
-get_event_window (GdkEventTranslator *translator,
- XEvent *xevent)
-{
- GdkDeviceManager *device_manager;
- GdkDisplay *display;
- GdkWindow *window;
-
- device_manager = GDK_DEVICE_MANAGER (translator);
- display = gdk_device_manager_get_display (device_manager);
- window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);
-
- /* Apply keyboard grabs to non-native windows */
- if (xevent->type == KeyPress || xevent->type == KeyRelease)
- {
- GdkDeviceGrabInfo *info;
- gulong serial;
-
- serial = _gdk_display_get_next_serial (display);
- info = _gdk_display_has_device_grab (display,
- GDK_DEVICE_MANAGER_CORE (device_manager)->core_keyboard,
- serial);
- if (info &&
- (!is_parent_of (info->window, window) ||
- !info->owner_events))
- {
- /* Report key event against grab window */
- window = info->window;
- }
- }
-
- return window;
-}
-
-static gboolean
-gdk_device_manager_core_translate_event (GdkEventTranslator *translator,
- GdkDisplay *display,
- GdkEvent *event,
- XEvent *xevent)
-{
- GdkDeviceManagerCore *device_manager;
- GdkWindow *window;
- GdkWindowImplX11 *window_impl = NULL;
- gboolean return_val;
- GdkToplevelX11 *toplevel = NULL;
- GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
-
- device_manager = GDK_DEVICE_MANAGER_CORE (translator);
- return_val = FALSE;
-
- window = get_event_window (translator, xevent);
-
- if (window)
- {
- if (GDK_WINDOW_DESTROYED (window) || !GDK_IS_WINDOW (window))
- return FALSE;
-
- toplevel = _gdk_x11_window_get_toplevel (window);
- window_impl = GDK_WINDOW_IMPL_X11 (window->impl);
- g_object_ref (window);
- }
-
- event->any.window = window;
- event->any.send_event = xevent->xany.send_event ? TRUE : FALSE;
-
- if (window && GDK_WINDOW_DESTROYED (window))
- {
- if (xevent->type != DestroyNotify)
- {
- return_val = FALSE;
- goto done;
- }
- }
-
- if (window &&
- (xevent->type == MotionNotify ||
- xevent->type == ButtonRelease))
- {
- if (_gdk_x11_moveresize_handle_event (xevent))
- {
- return_val = FALSE;
- goto done;
- }
- }
-
- /* We do a "manual" conversion of the XEvent to a
- * GdkEvent. The structures are mostly the same so
- * the conversion is fairly straightforward. We also
- * optionally print debugging info regarding events
- * received.
- */
-
- return_val = TRUE;
-
- switch (xevent->type)
- {
- case KeyPress:
- if (window == NULL)
- {
- return_val = FALSE;
- break;
- }
- translate_key_event (display, device_manager, event, xevent);
- set_user_time (window, event);
- break;
-
- case KeyRelease:
- if (window == NULL)
- {
- return_val = FALSE;
- break;
- }
-
- /* Emulate detectable auto-repeat by checking to see
- * if the next event is a key press with the same
- * keycode and timestamp, and if so, ignoring the event.
- */
-
- if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
- {
- XEvent next_event;
-
- XPeekEvent (xevent->xkey.display, &next_event);
-
- if (next_event.type == KeyPress &&
- next_event.xkey.keycode == xevent->xkey.keycode &&
- next_event.xkey.time == xevent->xkey.time)
- {
- return_val = FALSE;
- break;
- }
- }
-
- translate_key_event (display, device_manager, event, xevent);
- break;
-
- case ButtonPress:
- GDK_NOTE (EVENTS,
- g_message ("button press:\t\twindow: %ld x,y: %d %d button: %d",
- xevent->xbutton.window,
- xevent->xbutton.x, xevent->xbutton.y,
- xevent->xbutton.button));
-
- if (window == NULL)
- {
- return_val = FALSE;
- break;
- }
-
- /* If we get a ButtonPress event where the button is 4 or 5,
- it's a Scroll event */
- switch (xevent->xbutton.button)
- {
- case 4: /* up */
- case 5: /* down */
- case 6: /* left */
- case 7: /* right */
- event->scroll.type = GDK_SCROLL;
-
- if (xevent->xbutton.button == 4)
- event->scroll.direction = GDK_SCROLL_UP;
- else if (xevent->xbutton.button == 5)
- event->scroll.direction = GDK_SCROLL_DOWN;
- else if (xevent->xbutton.button == 6)
- event->scroll.direction = GDK_SCROLL_LEFT;
- else
- event->scroll.direction = GDK_SCROLL_RIGHT;
-
- event->scroll.window = window;
- event->scroll.time = xevent->xbutton.time;
- event->scroll.x = (gdouble) xevent->xbutton.x;
- event->scroll.y = (gdouble) xevent->xbutton.y;
- event->scroll.x_root = (gdouble) xevent->xbutton.x_root;
- event->scroll.y_root = (gdouble) xevent->xbutton.y_root;
- event->scroll.state = (GdkModifierType) xevent->xbutton.state;
- event->scroll.device = device_manager->core_pointer;
-
- if (!set_screen_from_root (display, event, xevent->xbutton.root))
- {
- return_val = FALSE;
- break;
- }
-
- break;
-
- default:
- event->button.type = GDK_BUTTON_PRESS;
- event->button.window = window;
- event->button.time = xevent->xbutton.time;
- event->button.x = (gdouble) xevent->xbutton.x;
- event->button.y = (gdouble) xevent->xbutton.y;
- event->button.x_root = (gdouble) xevent->xbutton.x_root;
- event->button.y_root = (gdouble) xevent->xbutton.y_root;
- event->button.axes = NULL;
- event->button.state = (GdkModifierType) xevent->xbutton.state;
- event->button.button = xevent->xbutton.button;
- event->button.device = device_manager->core_pointer;
-
- if (!set_screen_from_root (display, event, xevent->xbutton.root))
- return_val = FALSE;
-
- break;
- }
-
- set_user_time (window, event);
-
- break;
-
- case ButtonRelease:
- GDK_NOTE (EVENTS,
- g_message ("button release:\twindow: %ld x,y: %d %d button: %d",
- xevent->xbutton.window,
- xevent->xbutton.x, xevent->xbutton.y,
- xevent->xbutton.button));
-
- if (window == NULL)
- {
- return_val = FALSE;
- break;
- }
-
- /* We treat button presses as scroll wheel events, so ignore the release */
- if (xevent->xbutton.button == 4 || xevent->xbutton.button == 5 ||
- xevent->xbutton.button == 6 || xevent->xbutton.button == 7)
- {
- return_val = FALSE;
- break;
- }
-
- event->button.type = GDK_BUTTON_RELEASE;
- event->button.window = window;
- event->button.time = xevent->xbutton.time;
- event->button.x = (gdouble) xevent->xbutton.x;
- event->button.y = (gdouble) xevent->xbutton.y;
- event->button.x_root = (gdouble) xevent->xbutton.x_root;
- event->button.y_root = (gdouble) xevent->xbutton.y_root;
- event->button.axes = NULL;
- event->button.state = (GdkModifierType) xevent->xbutton.state;
- event->button.button = xevent->xbutton.button;
- event->button.device = device_manager->core_pointer;
-
- if (!set_screen_from_root (display, event, xevent->xbutton.root))
- return_val = FALSE;
-
- break;
-
- case MotionNotify:
- GDK_NOTE (EVENTS,
- g_message ("motion notify:\t\twindow: %ld x,y: %d %d hint: %s",
- xevent->xmotion.window,
- xevent->xmotion.x, xevent->xmotion.y,
- (xevent->xmotion.is_hint) ? "true" : "false"));
-
- if (window == NULL)
- {
- return_val = FALSE;
- break;
- }
-
- event->motion.type = GDK_MOTION_NOTIFY;
- event->motion.window = window;
- event->motion.time = xevent->xmotion.time;
- event->motion.x = (gdouble) xevent->xmotion.x;
- event->motion.y = (gdouble) xevent->xmotion.y;
- event->motion.x_root = (gdouble) xevent->xmotion.x_root;
- event->motion.y_root = (gdouble) xevent->xmotion.y_root;
- event->motion.axes = NULL;
- event->motion.state = (GdkModifierType) xevent->xmotion.state;
- event->motion.is_hint = xevent->xmotion.is_hint;
- event->motion.device = device_manager->core_pointer;
-
- if (!set_screen_from_root (display, event, xevent->xbutton.root))
- {
- return_val = FALSE;
- break;
- }
-
- break;
-
- case EnterNotify:
- GDK_NOTE (EVENTS,
- g_message ("enter notify:\t\twindow: %ld detail: %d subwin: %ld",
- xevent->xcrossing.window,
- xevent->xcrossing.detail,
- xevent->xcrossing.subwindow));
-
- if (window == NULL)
- {
- return_val = FALSE;
- break;
- }
-
- if (!set_screen_from_root (display, event, xevent->xbutton.root))
- {
- return_val = FALSE;
- break;
- }
-
- event->crossing.type = GDK_ENTER_NOTIFY;
- event->crossing.window = window;
- gdk_event_set_device (event, device_manager->core_pointer);
-
- /* If the subwindow field of the XEvent is non-NULL, then
- * lookup the corresponding GdkWindow.
- */
- if (xevent->xcrossing.subwindow != None)
- event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
- else
- event->crossing.subwindow = NULL;
-
- event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = (gdouble) xevent->xcrossing.x;
- event->crossing.y = (gdouble) xevent->xcrossing.y;
- event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
- event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
-
- event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
- event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
-
- event->crossing.focus = xevent->xcrossing.focus;
- event->crossing.state = xevent->xcrossing.state;
-
- break;
-
- case LeaveNotify:
- GDK_NOTE (EVENTS,
- g_message ("leave notify:\t\twindow: %ld detail: %d subwin: %ld",
- xevent->xcrossing.window,
- xevent->xcrossing.detail, xevent->xcrossing.subwindow));
-
- if (window == NULL)
- {
- return_val = FALSE;
- break;
- }
-
- if (!set_screen_from_root (display, event, xevent->xbutton.root))
- {
- return_val = FALSE;
- break;
- }
-
- event->crossing.type = GDK_LEAVE_NOTIFY;
- event->crossing.window = window;
- gdk_event_set_device (event, device_manager->core_pointer);
-
- /* If the subwindow field of the XEvent is non-NULL, then
- * lookup the corresponding GdkWindow.
- */
- if (xevent->xcrossing.subwindow != None)
- event->crossing.subwindow = gdk_x11_window_lookup_for_display (display, xevent->xcrossing.subwindow);
- else
- event->crossing.subwindow = NULL;
-
- event->crossing.time = xevent->xcrossing.time;
- event->crossing.x = (gdouble) xevent->xcrossing.x;
- event->crossing.y = (gdouble) xevent->xcrossing.y;
- event->crossing.x_root = (gdouble) xevent->xcrossing.x_root;
- event->crossing.y_root = (gdouble) xevent->xcrossing.y_root;
-
- event->crossing.mode = translate_crossing_mode (xevent->xcrossing.mode);
- event->crossing.detail = translate_notify_type (xevent->xcrossing.detail);
-
- event->crossing.focus = xevent->xcrossing.focus;
- event->crossing.state = xevent->xcrossing.state;
-
- break;
-
- /* We only care about focus events that indicate that _this_
- * window (not a ancestor or child) got or lost the focus
- */
- case FocusIn:
- GDK_NOTE (EVENTS,
- g_message ("focus in:\t\twindow: %ld, detail: %s, mode: %s",
- xevent->xfocus.window,
- notify_details[xevent->xfocus.detail],
- notify_modes[xevent->xfocus.mode]));
-
- if (toplevel)
- {
- gboolean had_focus = HAS_FOCUS (toplevel);
-
- switch (xevent->xfocus.detail)
- {
- case NotifyAncestor:
- case NotifyVirtual:
- /* When the focus moves from an ancestor of the window to
- * the window or a descendent of the window, *and* the
- * pointer is inside the window, then we were previously
- * receiving keystroke events in the has_pointer_focus
- * case and are now receiving them in the
- * has_focus_window case.
- */
- if (toplevel->has_pointer &&
- xevent->xfocus.mode != NotifyGrab &&
- xevent->xfocus.mode != NotifyUngrab)
- toplevel->has_pointer_focus = FALSE;
-
- /* fall through */
- case NotifyNonlinear:
- case NotifyNonlinearVirtual:
- if (xevent->xfocus.mode != NotifyGrab &&
- xevent->xfocus.mode != NotifyUngrab)
- toplevel->has_focus_window = TRUE;
- /* We pretend that the focus moves to the grab
- * window, so we pay attention to NotifyGrab
- * NotifyUngrab, and ignore NotifyWhileGrabbed
- */
- if (xevent->xfocus.mode != NotifyWhileGrabbed)
- toplevel->has_focus = TRUE;
- break;
- case NotifyPointer:
- /* The X server sends NotifyPointer/NotifyGrab,
- * but the pointer focus is ignored while a
- * grab is in effect
- */
- if (xevent->xfocus.mode != NotifyGrab &&
- xevent->xfocus.mode != NotifyUngrab)
- toplevel->has_pointer_focus = TRUE;
- break;
- case NotifyInferior:
- case NotifyPointerRoot:
- case NotifyDetailNone:
- break;
- }
-
- if (HAS_FOCUS (toplevel) != had_focus)
- generate_focus_event (device_manager, window, TRUE);
- }
- break;
- case FocusOut:
- GDK_NOTE (EVENTS,
- g_message ("focus out:\t\twindow: %ld, detail: %s, mode: %s",
- xevent->xfocus.window,
- notify_details[xevent->xfocus.detail],
- notify_modes[xevent->xfocus.mode]));
-
- if (toplevel)
- {
- gboolean had_focus = HAS_FOCUS (toplevel);
-
- switch (xevent->xfocus.detail)
- {
- case NotifyAncestor:
- case NotifyVirtual:
- /* When the focus moves from the window or a descendent
- * of the window to an ancestor of the window, *and* the
- * pointer is inside the window, then we were previously
- * receiving keystroke events in the has_focus_window
- * case and are now receiving them in the
- * has_pointer_focus case.
- */
- if (toplevel->has_pointer &&
- xevent->xfocus.mode != NotifyGrab &&
- xevent->xfocus.mode != NotifyUngrab)
- toplevel->has_pointer_focus = TRUE;
-
- /* fall through */
- case NotifyNonlinear:
- case NotifyNonlinearVirtual:
- if (xevent->xfocus.mode != NotifyGrab &&
- xevent->xfocus.mode != NotifyUngrab)
- toplevel->has_focus_window = FALSE;
- if (xevent->xfocus.mode != NotifyWhileGrabbed)
- toplevel->has_focus = FALSE;
- break;
- case NotifyPointer:
- if (xevent->xfocus.mode != NotifyGrab &&
- xevent->xfocus.mode != NotifyUngrab)
- toplevel->has_pointer_focus = FALSE;
- break;
- case NotifyInferior:
- case NotifyPointerRoot:
- case NotifyDetailNone:
- break;
- }
-
- if (HAS_FOCUS (toplevel) != had_focus)
- generate_focus_event (device_manager, window, FALSE);
- }
- break;
-
- default:
- return_val = FALSE;
- }
-
- done:
- if (return_val)
- {
- if (event->any.window)
- g_object_ref (event->any.window);
-
- if (((event->any.type == GDK_ENTER_NOTIFY) ||
- (event->any.type == GDK_LEAVE_NOTIFY)) &&
- (event->crossing.subwindow != NULL))
- g_object_ref (event->crossing.subwindow);
- }
- else
- {
- /* Mark this event as having no resources to be freed */
- event->any.window = NULL;
- event->any.type = GDK_NOTHING;
- }
-
- if (window)
- g_object_unref (window);
-
- return return_val;
-}
-
-static GList *
-gdk_device_manager_core_list_devices (GdkDeviceManager *device_manager,
- GdkDeviceType type)
-{
- GdkDeviceManagerCore *device_manager_core;
- GList *devices = NULL;
-
- if (type == GDK_DEVICE_TYPE_MASTER)
- {
- device_manager_core = (GdkDeviceManagerCore *) device_manager;
- devices = g_list_prepend (devices, device_manager_core->core_keyboard);
- devices = g_list_prepend (devices, device_manager_core->core_pointer);
- }
-
- return devices;
-}
-
-static GdkDevice *
-gdk_device_manager_core_get_client_pointer (GdkDeviceManager *device_manager)
-{
- GdkDeviceManagerCore *device_manager_core;
-
- device_manager_core = (GdkDeviceManagerCore *) device_manager;
- return device_manager_core->core_pointer;
-}
+++ /dev/null
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GDK_DEVICE_MANAGER_CORE_H__
-#define __GDK_DEVICE_MANAGER_CORE_H__
-
-#include "gdkdevicemanagerprivate.h"
-
-G_BEGIN_DECLS
-
-#define GDK_TYPE_DEVICE_MANAGER_CORE (gdk_device_manager_core_get_type ())
-#define GDK_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCore))
-#define GDK_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
-#define GDK_IS_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_DEVICE_MANAGER_CORE))
-#define GDK_IS_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_DEVICE_MANAGER_CORE))
-#define GDK_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_DEVICE_MANAGER_CORE, GdkDeviceManagerCoreClass))
-
-typedef struct _GdkDeviceManagerCore GdkDeviceManagerCore;
-typedef struct _GdkDeviceManagerCoreClass GdkDeviceManagerCoreClass;
-
-struct _GdkDeviceManagerCore
-{
- GdkDeviceManager parent_object;
- GdkDevice *core_pointer;
- GdkDevice *core_keyboard;
-};
-
-struct _GdkDeviceManagerCoreClass
-{
- GdkDeviceManagerClass parent_class;
-};
-
-GType gdk_device_manager_core_get_type (void) G_GNUC_CONST;
-
-
-G_END_DECLS
-
-#endif /* __GDK_DEVICE_MANAGER_CORE_H__ */
#include "config.h"
-#include "gdkdevicemanager-core.h"
+#include "gdkx11devicemanager-core.h"
#ifdef XINPUT_XFREE
#include "gdkdevicemanager-xi.h"
#ifdef XINPUT_2
GDK_NOTE (INPUT, g_print ("Creating core device manager\n"));
- return g_object_new (GDK_TYPE_DEVICE_MANAGER_CORE,
+ return g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_CORE,
"display", display,
NULL);
}
GdkDeviceType type);
-G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI, gdk_device_manager_xi, GDK_TYPE_DEVICE_MANAGER_CORE,
+G_DEFINE_TYPE_WITH_CODE (GdkDeviceManagerXI, gdk_device_manager_xi, GDK_TYPE_X11_DEVICE_MANAGER_CORE,
G_IMPLEMENT_INTERFACE (GDK_TYPE_EVENT_TRANSLATOR,
gdk_device_manager_xi_event_translator_init))
#ifndef __GDK_DEVICE_MANAGER_XI_H__
#define __GDK_DEVICE_MANAGER_XI_H__
-#include "gdkdevicemanager-core.h"
+#include "gdkx11devicemanager-core.h"
G_BEGIN_DECLS
struct _GdkDeviceManagerXI
{
- GdkDeviceManagerCore parent_object;
+ GdkX11DeviceManagerCore parent_object;
GdkDevice *core_pointer;
GdkDevice *core_keyboard;
struct _GdkDeviceManagerXIClass
{
- GdkDeviceManagerCoreClass parent_class;
+ GdkX11DeviceManagerCoreClass parent_class;
};
GType gdk_device_manager_xi_get_type (void) G_GNUC_CONST;
#define __GDKX_H_INSIDE__
#include <gdk/x11/gdkx11cursor.h>
+#include <gdk/x11/gdkx11device-core.h>
+#include <gdk/x11/gdkx11devicemanager-core.h>
#include <gdk/x11/gdkx11display.h>
#include <gdk/x11/gdkx11displaymanager.h>
#include <gdk/x11/gdkx11keys.h>
--- /dev/null
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_X11_DEVICE_CORE_H__
+#define __GDK_X11_DEVICE_CORE_H__
+
+#include "gdkdeviceprivate.h"
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_X11_DEVICE_CORE (gdk_x11_device_core_get_type ())
+#define GDK_X11_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCore))
+#define GDK_X11_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCoreClass))
+#define GDK_IS_X11_DEVICE_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_X11_DEVICE_CORE))
+#define GDK_IS_X11_DEVICE_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_X11_DEVICE_CORE))
+#define GDK_X11_DEVICE_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_X11_DEVICE_CORE, GdkX11DeviceCoreClass))
+
+typedef struct _GdkX11DeviceCore GdkX11DeviceCore;
+typedef struct _GdkX11DeviceCoreClass GdkX11DeviceCoreClass;
+
+struct _GdkX11DeviceCore
+{
+ GdkDevice parent_instance;
+};
+
+struct _GdkX11DeviceCoreClass
+{
+ GdkDeviceClass parent_class;
+};
+
+GType gdk_x11_device_core_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __GDK_X11_DEVICE_CORE_H__ */
--- /dev/null
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_X11_DEVICE_MANAGER_CORE_H__
+#define __GDK_X11_DEVICE_MANAGER_CORE_H__
+
+#include "gdkdevicemanagerprivate.h"
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_X11_DEVICE_MANAGER_CORE (gdk_x11_device_manager_core_get_type ())
+#define GDK_X11_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCore))
+#define GDK_X11_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCoreClass))
+#define GDK_IS_X11_DEVICE_MANAGER_CORE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE))
+#define GDK_IS_X11_DEVICE_MANAGER_CORE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), GDK_TYPE_X11_DEVICE_MANAGER_CORE))
+#define GDK_X11_DEVICE_MANAGER_CORE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDK_TYPE_X11_DEVICE_MANAGER_CORE, GdkX11DeviceManagerCoreClass))
+
+typedef struct _GdkX11DeviceManagerCore GdkX11DeviceManagerCore;
+typedef struct _GdkX11DeviceManagerCoreClass GdkX11DeviceManagerCoreClass;
+
+struct _GdkX11DeviceManagerCore
+{
+ GdkDeviceManager parent_object;
+ GdkDevice *core_pointer;
+ GdkDevice *core_keyboard;
+};
+
+struct _GdkX11DeviceManagerCoreClass
+{
+ GdkDeviceManagerClass parent_class;
+};
+
+GType gdk_x11_device_manager_core_get_type (void) G_GNUC_CONST;
+
+
+G_END_DECLS
+
+#endif /* __GDK_X11_DEVICE_MANAGER_CORE_H__ */